﻿using System.Collections.Generic;
using Business.Entities.TFS;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace Data.ServiceAgents.TfsAccess
{
    /// <summary>
    /// This class give the access to the Team Foundation Server objetcs.
    /// </summary>
    public class SourceControl
    {
        /// <summary>
        /// The team foundation server URL
        /// </summary>
        protected string str_tfs_server;

        /// <summary>
        /// Creates a new SourceControl class
        /// </summary>
        /// <param name="str_tfs_server">The team foundation server URL</param>
        public SourceControl(string str_tfs_server)
        {
            this.str_tfs_server = str_tfs_server;
        }

        /// <summary>
        /// Get the pendindg changes in the server by user
        /// </summary>
        /// <returns>A TFS_Users collection containing all users with pending changes, its workspaces and its pending changes files information</returns>
        public Dictionary<string, TFS_User> getPendingChangesByUsers()
        {
            Dictionary<string, TFS_User> colTFS_User = new Dictionary<string, TFS_User>();

            // Connection to TFS Version Control    
            TeamFoundationServer oTeamFoundationServer = TeamFoundationServerFactory.GetServer(str_tfs_server);
            VersionControlServer oVersionControlServer = (VersionControlServer)oTeamFoundationServer.GetService(typeof(VersionControlServer));
 
            // Pulling the pending changes    
            PendingSet[] colPendingSet = oVersionControlServer.GetPendingSets(new string[] { "$/" }, RecursionType.Full);

            foreach (PendingSet oPendingSet in colPendingSet)
            {
                if (oPendingSet.PendingChanges != null)
                {
                    TFS_User oTFS_User = this.TFS_UserFactory(colTFS_User, oPendingSet);
                    TFS_Workspace oTFS_Workspace = this.TFS_WorkspaceFactory(oTFS_User, oPendingSet);

                    foreach (PendingChange oPendingChange in oPendingSet.PendingChanges)
                    {
                        TFS_PendingChanges oTFS_PendingChanges = new TFS_PendingChanges();
                        oTFS_PendingChanges.ServerPath = oPendingChange.ServerItem;
                        oTFS_PendingChanges.LocalFile = oPendingChange.LocalItem;
                        oTFS_PendingChanges.ChangeType = oPendingChange.ChangeTypeName;
                        oTFS_PendingChanges.CheckoutDate = oPendingChange.CreationDate;

                        oTFS_Workspace.PendingChanges.Add(oTFS_PendingChanges);
                    }
                }
            }

            return colTFS_User;
        }

        /// <summary>
        /// Creates a new TFS_User if not exists, or gets the existing one
        /// </summary>
        /// <param name="colTFS_User">The existing TFS_User colletion</param>
        /// <param name="oPendingSet">The pending set objetc that contains the user information to create / obtain</param>
        /// <returns>The TFS_User created or obteined</returns>
        private TFS_User TFS_UserFactory(Dictionary<string, TFS_User> colTFS_User, PendingSet oPendingSet)
        {
            TFS_User oTFS_User;

            if (!colTFS_User.ContainsKey(oPendingSet.OwnerName))
            {
                oTFS_User = new TFS_User();
                oTFS_User.Workspaces = new Dictionary<string, TFS_Workspace>();
                oTFS_User.UserName = oPendingSet.OwnerName;

                colTFS_User.Add(oPendingSet.OwnerName, oTFS_User);
            }
            else
            {
                oTFS_User = colTFS_User[oPendingSet.OwnerName];
            }

            return oTFS_User;
        }

        /// <summary>
        /// Creates a new TFS_Workspace if not exists, or gets the existing one
        /// </summary>
        /// <param name="oTFS_User">The TFS_User who own the Workspace</param>
        /// <param name="oPendingSet">The pending set objetc that contains the workspace information to create / obtain</param>
        /// <returns>The TFS_Workspace created or obteined</returns>
        private TFS_Workspace TFS_WorkspaceFactory(TFS_User oTFS_User, PendingSet oPendingSet)
        {
            TFS_Workspace oTFS_Workspace;

            if (!oTFS_User.Workspaces.ContainsKey(oPendingSet.Name))
            {
                oTFS_Workspace = new TFS_Workspace();
                oTFS_Workspace.PendingChanges = new List<TFS_PendingChanges>();
                oTFS_Workspace.Type = oPendingSet.Type.ToString();
                oTFS_Workspace.WorkspaceName = oPendingSet.Name;
                oTFS_Workspace.Computer = oPendingSet.Computer;

                oTFS_User.Workspaces.Add(oPendingSet.Name, oTFS_Workspace);
            }
            else
            {
                oTFS_Workspace = oTFS_User.Workspaces[oPendingSet.Name];
            }

            return oTFS_Workspace;
        }
    }
}
